#ifndef YIGPACKETLISTENER_H
#define YIGPACKETLISTENER_H

// System includes
#include <oscpack/osc/OscPacketListener.h>
#include <QObject>
#include <QPoint>

/**
*   YigPacketListener
*   Listenes for and parses OSC messages
*/
class YigPacketListener : public QObject, public osc::OscPacketListener
{
    Q_OBJECT

signals:

    /**
    *   emitted anytime the server replies with a /status message
    *   @param QString The current boot status of the sc synth server: "inactive", "booting", or "running"
    *   @param int The current number of synths running on the server
    *   @param float The average CPU taken up by the server
    *   @param float The Peak CPU taken up by the server
    */
    void serverStatus(QString serverBootStatus, int numSynths, float avgCPU, float peakCPU);

    /**
    *   emitted when a new chat message comes in over osc
    *   @param QString The new message
    */
    void chatMessage(QString message);

    /**
    *   emitted when an osc messages requests a new synth addition
    *   @param QString mapKey The map key for the synth to be created
    *   @param QString The name of the synth def to use for this synth
    *   @param QPoint point where the synth will be created
    *   @param float the randomized first parameter
    *   @param float the randomized second parameter
    */
    void addSynth(QString mapKey, QString synthName, QPoint point, float param1, float param2);

    /**
    *   remove a synth from
    *   @param QString The map key for the synth to be removed
    */
    void removeSynth(QString mapKey);

    /**
    *   updates a synth position from the network
    *   @param QString the map key of the synth to update
    *   @param int The new x position of the synth
    */
    void updateSynthPositionX(QString mapKey, int xPos);

    /**
    *   updates a synth position from the network
    *   @param QString the map key of the synth to update
    *   @param int The new y position of the synth
    */
    void updateSynthPositionY(QString mapKey, int yPos);

    /**
    *   updates a synth parameter modulation from the network
    *   @param const char* The map key for the synth
    *   @param float the new value of the parameter
    */
    void updateSynthParam1(QString mapKey, float param1);

    /**
    *   updates a synth parameter modulation from the network
    *   @param const char* The map key for the synth
    *   @param float the new value of the parameter
    */
    void updateSynthParam2(QString mapKey, float param2);

    /**
    *   called when the selected state of the synth changes locally
    *   @param QString the map key for the synth
    *   @param QString the userName of the user that has selected or unselected the synth
    */
    void updateSynthSelected(QString mapKey, QString userName);

    /**
    *   emitted when a /setSyncArg message comes in for the synth name. We use it to check for synths not in our map
    *   @param QString The map key of the synth
    *   @paragraph QString The synth name of the synth
    */
    void synthNameSync(QString mapKey, QString synthName);

    /**
    *   addPeer emitted when a new peer logs on to OSCthulhu
    *   @param QString the screen name of the user to add
    */
    void addPeer(QString userName);

    /**
    *   removePeer emitted when a current peer logs off OSCthulhu
    *   @param QString the screen name of the user to remove
    */
    void removePeer(QString userName);

    /**
    *   updates a cursor position from the network
    *   @param QString the userName of the cursor to update
    *   @param int The new x position of the cursor
    */
    void updateCursorPositionX(QString userName, int xPos);

    /**
    *   updates a cursor position from the network
    *   @param QString the userName of the cursor to update
    *   @param int The new y position of the cursor
    */
    void updateCursorPositionY(QString userName, int yPos);

    /** called when we get a reply for the user name */
    void userNameReply();

protected:

    void ProcessMessage(const osc::ReceivedMessage &message, const IpEndpointName &remoteEndpoint);

};

#endif // YIGPACKETLISTENER_H
